<template>
  <div>
    <ElCard style="margin-bottom: 10px; height: 80px">
      <ElForm inline style="display: flex; justify-content: space-between; align-items: center">
        <ElFormItem label="职位搜索:">
          <ElInput placeholder="请输入需要搜索职位" v-model="seekRoleName"> </ElInput>
        </ElFormItem>
        <ElFormItem>
          <el-button type="primary" size="default" @click="seek" :disabled="!seekRoleName"
            >搜索</el-button
          >
          <el-button type="primary" size="default" @click="reset">重置</el-button>
        </ElFormItem>
      </ElForm>
    </ElCard>
    <ElCard>
      <div style="margin-bottom: 10px">
        <el-button type="primary" size="default" @click="addRolePosition" v-has="'btn.Role.add'">
          添加职位
        </el-button>
      </div>
      <ElTable border :data="roleData" style="margin-bottom: 10px">
        <ElTableColumn type="index" label="#" align="center"> </ElTableColumn>
        <ElTableColumn type="" label="ID" align="center" prop="id"> </ElTableColumn>
        <ElTableColumn
          type=""
          label="职位名称"
          align="center"
          prop="roleName"
          show-overflow-tooltip
        >
        </ElTableColumn>
        <ElTableColumn
          type=""
          label="创建时间"
          align="center"
          prop="createTime"
          show-overflow-tooltip
        >
        </ElTableColumn>
        <ElTableColumn
          type=""
          label="更新时间"
          align="center"
          prop="updateTime"
          show-overflow-tooltip
        >
        </ElTableColumn>
        <ElTableColumn label="操作" align="center" width="300px">
          <template #="{ row, $index }">
            <el-button
              type="primary"
              size="small"
              icon="user"
              @click="OpenDrawer(row)"
              v-has="'btn.Role.assgin'"
              >按钮菜单权限</el-button
            >
            <el-button
              type="primary"
              size="small"
              icon="edit"
              @click="updataRolePositionName(row)"
              v-has="'btn.Role.update'"
              >编辑</el-button
            >
            <el-button
              type="primary"
              size="small"
              icon="Delete"
              @click="DelRole(row)"
              v-has="'btn.Role.remove'"
              >删除</el-button
            >
          </template>
        </ElTableColumn>
      </ElTable>
      <div>
        <pagination
          v-model:page-no="pageNo"
          v-model:limit="limit"
          v-model:total="total"
          :get-pag-data="getRoleList"
          :page-sizes="[10, 20, 30, 40]"
        ></pagination>
      </div>
    </ElCard>
    <el-dialog
      v-model="dialogVisible"
      :title="roleParam.id ? '更新职位' : '添加职位'"
      :before-close="cancalDialog"
    >
      <ElForm ref="formRef" :rules="rule" :model="roleParam">
        <ElFormItem label="职位名称" label-width="80px" prop="roleName">
          <ElInput placeholder="请输入职位名称" v-model="roleParam.roleName"></ElInput>
        </ElFormItem>
      </ElForm>
      <template #footer>
        <el-button type="primary" @click="AddOrUpdataRole">确定</el-button>
        <el-button type="primary" @click="cancalDialog">取消</el-button>
      </template>
    </el-dialog>
    <el-drawer v-model="drawer" title="分配角色与按钮的权限" size="30%">
      <div>
        <el-tree
          ref="treeRef"
          style="max-width: 600px"
          :data="PermissionArr"
          show-checkbox
          node-key="id"
          :props="defaultProps"
          :default-checked-keys="SelectArr"
          default-expand-all
        />
      </div>
      <template #footer>
        <div style="flex: auto">
          <el-button @click="drawer = false">取消</el-button>
          <el-button type="primary" @click="UpdataUserPermissionOK">确定</el-button>
        </div>
      </template>
    </el-drawer>
  </div>
</template>

<script lang="ts" setup name="role">
import {
  reqAssignRolePermission,
  reqFindRoleIdOnPermission,
  reqGetPermission
} from '@/API/acl/permission'
import { reqAddRoleName, reqDelRoleList, reqHasRoleList, reqUpdataRoleName } from '@/API/acl/role'
import { RecordRoleData } from '@/API/acl/role/type'
import { FormRules } from 'element-plus'
import { onMounted, ref, reactive, nextTick } from 'vue'
let pageNo = ref(1)
let limit = ref(10)
let total = ref(0)
let seekRoleName = ref('')
let dialogVisible = ref(false)
let drawer = ref(false)
let roleData = ref<RecordRoleData[]>()
let roleParam = ref<RecordRoleData>({})
let formRef = ref()
let treeRef = ref()
let SelectArr = ref([])
let PermissionArr = ref([])
/* 给树形内指定数据值.其数据是对应我们传入数组中的属性. */
let defaultProps = {
  children: 'children',
  label: 'name'
}
const UpdataUserPermissionOK = async () => {
  let roleId = roleParam.value.id
  let arr1 = treeRef.value.getCheckedKeys()
  let arr2 = treeRef.value.getHalfCheckedKeys()
  let permissionId = arr1.concat(arr2)
  let reuslt = await reqAssignRolePermission(roleId, permissionId)
  if (reuslt.code == 200) {
    drawer.value = false
    ElMessage({ type: 'success', message: '分配权限成功' })
    window.location.reload()
  }
}
const getRoleList = async (pager = 1) => {
  pageNo.value = pager
  let result = await reqHasRoleList(pageNo.value, limit.value, seekRoleName.value)
  result.code == 200
    ? ((roleData.value = result.data.records), (total.value = result.data.total))
    : console.log(result.message)
}
const seek = () => {
  getRoleList()
}
const reset = () => {
  seekRoleName.value = ''
  getRoleList()
}
const addRolePosition = () => {
  console.log(formRef.value)

  formRef.value?.resetFields()
  Object.assign(roleParam.value, {
    id: 0,
    roleName: ''
  })
  dialogVisible.value = true
}
const cancalDialog = () => {
  dialogVisible.value = false
}
const updataRolePositionName = (row) => {
  dialogVisible.value = true
  Object.assign(roleParam.value, row)
  nextTick(() => {
    formRef.value.resetFields()
  })
}
const DelRole = (row) => {
  ElMessageBox.confirm('确定删除角色数据吗?', '删除', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  })
    .then(async () => {
      let result = await reqDelRoleList(row.id)
      if (result.code == 200) {
        ElMessage({
          type: 'success',
          message: '删除成功'
        })
        getRoleList()
      } else {
        console.log(result.message)
      }
    })
    .catch(() => {
      ElMessage({
        type: 'info',
        message: '取消'
      })
    })
}
const OpenDrawer = async (row) => {
  drawer.value = true
  Object.assign(roleParam.value, row)
  let reuslt = await reqFindRoleIdOnPermission(roleParam.value.id)
  if (reuslt.code == 200) {
    PermissionArr.value = reuslt.data
    SelectArr.value = filterSelectArr(PermissionArr.value, [])
  }
}
/*  过滤树形中被选中的数据的方法
      算法
        filterSelectArr 函数实现了一个递归算法，用于遍历一个可能包含嵌套子数组（或称为子节点）的数组（或树形结构）。这个算法通过以下步骤工作：

        遍历当前层级的所有元素：使用 forEach 循环遍历 allData 数组中的每个元素。
        检查条件：对于每个元素，检查它是否满足两个条件：select 属性为 true 且 level 属性等于 4。
        收集符合条件的元素：如果元素满足上述条件，则将其 id 添加到 initArr 数组中。
        递归调用：如果当前元素有 children 属性且 children 数组不为空，则递归调用 filterSelectArr 函数，传入 children 数组和相同的 initArr 数组。
        返回结果：当所有层级都被遍历后，函数返回 initArr 数组，该数组包含了所有满足条件的元素的 id。
*/
const filterSelectArr = (allData, initArr) => {
  allData.forEach((i) => {
    if (i.select && i.level == 4) {
      initArr.push(i.id)
    }
    if (i.children && i.children.length > 0) {
      filterSelectArr(i.children, initArr)
    }
  })
  return initArr
}
const roleName = (rule, value, cb) => {
  if (value.trim().length >= 2) {
    cb()
  } else {
    cb(new Error('职位名字至少为两位'))
  }
}
const rule = <FormRules>{
  roleName: [
    {
      validator: roleName,

      required: true,
      trigger: 'blur'
    }
  ]
}
const AddOrUpdataRole = async () => {
  await formRef.value.validate()
  if (roleParam.value.id) {
    let result = await reqUpdataRoleName(roleParam.value)
    result.code == 200 ? getRoleList(pageNo.value) : console.log(result.message)
    dialogVisible.value = false
  } else {
    let result = await reqAddRoleName(roleParam.value)
    result.code == 200 ? getRoleList() : console.log(result.message)
    dialogVisible.value = false
  }
}
const HasPermissionParam = async () => {
  let result = await reqGetPermission()
  if (result.code == 200) {
    PermissionArr.value = result.data
  }
}
onMounted(() => {
  getRoleList()
  HasPermissionParam()
})
</script>

<style scoped></style>
